package org.itydl.game.business

import org.itydl.game.Config
import org.itydl.game.enums.Direction
import org.itydl.game.model.View

/**
 * 表示所有可以移动物体（坦克、子弹）的能力，抽象为接口
 * Kotlin中的接口实现跟多层继承很类似，属性方法都可以重写
 */
interface Movable : View {
    /**
     * 移动的物体属性：
     * 移动速度、移动方向
     */
    // 速度
    val speed: Int

    // 方向
    val currentDirection: Direction

    /**
     * 接口定义实现，因为所有移动的物体都具备碰撞检测的逻辑
     * <p>
     * 是否发生碰撞，转换为 返回碰撞的方向，根据方向做是否碰撞处理
     * @return 是否发生了碰撞。碰撞的方向，可空，如果null表示没有发生碰撞（一直往该方向运动，碰撞了返回一个方向，表示在哪个方向碰撞的）
     */
    fun willCollication(block: Blockable): Direction?{

        // 当前x和y
        var x = this.x
        var y = this.y

        // 将来的x、y
        when (currentDirection) {
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }

        // 此时做检测碰撞的x、y都是下一个x，y(将来值)

        // 类似自动移动的坦克撞到墙以后，也属于碰撞操作
        if (x < 0) return Direction.LEFT// 向左移动与左墙碰撞
        if (x > Config.gameWidth - width) return Direction.RIGHT// 向右移动与右墙碰撞
        if (y < 0) return Direction.UP// 向上移动与上墙碰撞
        if (y > Config.gameHeight - height) return Direction.DOWN// 向下移动与下墙碰撞

        // 直接判断在什么时候碰撞困难，判断什么时候不碰撞简单，其它的就是碰撞了
        val isCollication = checkCollection(x, y, width, height, block.x, block.y, block.width, block.height)

        // 发生了碰撞，记录下当前碰撞的方向，返回
        return if (isCollication) currentDirection else null
    }

    /**
     * 通知移动物体发生碰撞
     * 1、碰撞的方法；2、碰撞的具体物体是谁
     * 可空类型，因为方向和阻挡块都是可能有可能没有
     */
    fun notifyCollication(direction: Direction?, blockable: Blockable?)
}